
local function trySetter(cls, self, key, val)
    if cls.__sets[key] then
        cls.__sets[key](self, key, val)
        return true
    end
    if cls.super and trySetter(cls.super, self, key, val) then
        return true
    end
    return false
end
local function tryGetter(cls, self, key)
    if cls.__gets[key] then
        return cls.__gets[key](self, key)
    end
    if cls.super then
        return tryGetter(cls.super, self, key)
    end
end
function Class(classname, super)
    local superType = type(super)
    local cls
 
    -- --如果父类既不是函数也不是table则说明父类为空
    if superType ~= "function" and superType ~= "table" then
---@diagnostic disable-next-line: cast-local-type
        superType = nil
        super = nil
    end
 
    -- --如果父类的类型是函数或者是C对象
    if superType == "function" or (super and super.__ctype == 1) then
        -- inherited from native C++ Object
        cls = {}
 
        --如果父类是表则复制成员并且设置这个类的继承信息
        --如果是函数类型则设置构造方法并且设置ctor函数
        if superType == "table" then
            -- copy fields from super
            for k,v in pairs(super) do cls[k] = v end
            cls.__create = super.__create
            cls.super    = super
        else
            cls.__create = super
            cls.ctor = function() end
        end
 
        --设置类型的名称
        cls.__cname = classname
        cls.__ctype = 1
 
        --定义该类型的创建实例的函数为基类的构造函数后复制到子类实例
        --并且调用子数的ctor方法
        function cls.new(...)
            local instance = cls.__create(...)
            -- copy fields from class to native object
            for k,v in pairs(cls) do instance[k] = v end
            instance.class = cls
            instance:ctor(...)
            return instance
        end
 
 
    else
        --如果是继承自普通的lua表,则设置一下原型，并且构造实例后也会调用ctor方法
        -- inherited from Lua Object
        if super then
            cls = {}
            setmetatable(cls, {__index = super})
            cls.super = super
        else
            cls = {ctor = function() end}
        end
 
        cls.__cname = classname
        cls.__ctype = 2 -- lua

        -- 模仿js 封装get set 属性
        cls.__gets = {}
        cls.__sets = {}
        cls.className = function(self)
            return self.__cname
        end
        cls.__index = function(self, key)
            local val = tryGetter(cls, self, key)
            if val then
                return val
            end
            val = rawget(self, key)
            if val then
                return val
            end
            if cls[key] then
                return cls[key]
            end
        end
        cls.__newindex = function(self, key, val)
            if trySetter(cls, self, key, val) then
                return
            end
            rawset(self, key, val)
        end

        function cls.defineProp(key, tbl)
            if tbl.get then cls.__gets[key] = tbl.get end
            if tbl.set then cls.__sets[key] = tbl.set end
        end
 
        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    end
 
    return cls
end

function IsClassOf(obj, cname)
    if type(obj) ~= 'table' then
        return false
    end
    if obj.__cname == cname then
        return true
    elseif obj.super then
        return IsClassOf(obj.super, cname)
    end
    return false
end